﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;
using VitCode.BaseDataPageCreator.Setting;
using VitCode.ObjectResolutionHelper;

namespace VitCode.BaseDataPageCreator
{
    /// <summary>
    /// 用于对象通过Excel导入模板进行批量导入时解析运行的附助类
    /// </summary>
    public class ImportHelper
    {
        protected string m_SettingFilePath;
        protected ObjXmlReader m_XmlReader;

        public ObjXmlReader InnerXmlReader
        {
            get { return m_XmlReader; }
        }
        
        public ImportHelper(string settingFilePath)
        {
            if(string.IsNullOrEmpty(settingFilePath))
                throw new ArgumentNullException("settingFilePath");
            if (!File.Exists(settingFilePath))
                throw new ArgumentException(settingFilePath + "文件不存在");
            m_SettingFilePath = settingFilePath;
            m_XmlReader = new ObjXmlReader(m_SettingFilePath);
        }

        /// <summary>
        /// 获取所以批量导入对象的设置节
        /// </summary>
        /// <returns></returns>
        public XmlNodeList GetClassNodes()
        {
            XmlNodeList reVal = null;
            const string xPath = "Setting/*";
            reVal = m_XmlReader.GetNodeList(xPath);
            return reVal;
        }

        /// <summary>
        /// 获取导入参数
        /// </summary>
        /// <returns>Key=Memo,Value=ClassName,TypeName</returns>
        public NameValueCollection GetImprotTypeInfo()
        {
            var nvc = new NameValueCollection();
            var nl = GetClassNodes();
            foreach(XmlNode n in nl)
            {
                var strMemo = m_XmlReader.GetNodeAttributeValue(n, ImportKeyInfo.MEMO, true);
                if(!string.IsNullOrEmpty(strMemo))
                    nvc.Add(strMemo,n.Name);

                foreach(XmlNode cn in n.ChildNodes)
                {
                    if (cn.Name != ImportKeyInfo.COLUMNS && cn.Name != ImportKeyInfo.CHECKS)
                    {
                        strMemo = m_XmlReader.GetNodeAttributeValue(cn, ImportKeyInfo.MEMO, false);
                        nvc.Add(strMemo,n.Name + "," + cn.Name);
                    }
                }
            }
            return nvc;
        }

        /// <summary>
        /// 获取导入对象的配置节点
        /// </summary>
        /// <param name="className">对象类型名称</param>
        /// <param name="typeName">对象类别名称(对象的二级业务划分)
        /// 所为的业务对象,就有可以一个数据持久化对象,通过TypeName可以划分为N个业务对象
        /// </param>
        /// <returns>业务对象的配置节</returns>
        public XmlNode GetImportObjNode(string className,string typeName)
        {
            XmlNodeList reVal = null;
            if (string.IsNullOrEmpty(className))
                throw new ArgumentNullException("className");
            var strTypeNamePath = "";
            if (!String.IsNullOrEmpty(typeName))
                strTypeNamePath = "/" + typeName;
            var xPath = "Setting/" + className + strTypeNamePath;
            reVal = m_XmlReader.GetNodeList(xPath);
            if (reVal == null || reVal.Count == 0)
                throw new ArgumentException("找不到ClassNode["+className+"]");
            if (reVal.Count > 1)
                throw new ArgumentException("找到多个ClassNode["+className+"]");
            return reVal[0];
        }

        /// <summary>
        /// 获取对象导入模板中列设置节的集合
        /// </summary>
        /// <param name="className">对象类型名称</param>
        /// <param name="typeName">对象类别名称(对象的二级业务划分)
        /// 所为的业务对象,就有可以一个数据持久化对象,通过TypeName可以划分为N个业务对象</param>
        /// <returns>对象导入模板中列设置节的集合</returns>
        public XmlNodeList GetColumnNodes(string className, string typeName)
        {
            XmlNodeList reVal = null;
            if (string.IsNullOrEmpty(className))
                throw new ArgumentNullException("className");
            var strTypeNamePath = "";
            if (!String.IsNullOrEmpty(typeName))
                strTypeNamePath = "/" + typeName;
            var xPath = "Setting/" + className + strTypeNamePath + "/" + ImportKeyInfo.COLUMNS + "/" + ImportKeyInfo.ITEM;
            reVal = m_XmlReader.GetNodeList(xPath);
            return reVal;
        }

        /// <summary>
        /// 获取对象导入模板中有唯一约束的配置节集合
        /// </summary>
        /// <param name="className">对象类型名称</param>
        /// <param name="typeName">对象类别名称(对象的二级业务划分)
        /// 所为的业务对象,就有可以一个数据持久化对象,通过TypeName可以划分为N个业务对象</param>
        /// <returns>导入模板中有唯一约束的配置节集合</returns>
        public XmlNodeList GetUniqueCheckNodes(string className, string typeName)
        {
            XmlNodeList reVal = null;
            if (string.IsNullOrEmpty(className))
                throw new ArgumentNullException("className");
            var strTypeNamePath = "";
            if (!String.IsNullOrEmpty(typeName))
                strTypeNamePath = "/" + typeName;
            var xPath = "Setting/" + className + strTypeNamePath + "/" + ImportKeyInfo.CHECKS + "/" +ImportKeyInfo.UNIQUE + "/" + ImportKeyInfo.ITEM;
            reVal = m_XmlReader.GetNodeList(xPath);
            return reVal;
        }

        /// <summary>
        /// 获取对象导入模板中有存在性约束的配置节集合
        /// </summary>
        /// <param name="className">对象类型名称</param>
        /// <param name="typeName">对象类别名称(对象的二级业务划分)
        /// 所为的业务对象,就有可以一个数据持久化对象,通过TypeName可以划分为N个业务对象</param>
        /// <returns>导入模板中有存在性约束的配置节集合</returns>
        public XmlNodeList GetExistsCheckNodes(string className, string typeName)
        {
            XmlNodeList reVal = null;
            if (string.IsNullOrEmpty(className))
                throw new ArgumentNullException("className");
            var strTypeNamePath = "";
            if (!String.IsNullOrEmpty(typeName))
                strTypeNamePath = "/" + typeName;
            var xPath = "Setting/" + className + strTypeNamePath + "/" + ImportKeyInfo.CHECKS + "/" + ImportKeyInfo.EXISTS + "/" + ImportKeyInfo.ITEM;
            reVal = m_XmlReader.GetNodeList(xPath);
            return reVal;
        }

        /// <summary>
        /// 获取对象导入模板中有非空约束的配置节集合
        /// </summary>
        /// <param name="className">对象类型名称</param>
        /// <param name="typeName">对象类别名称(对象的二级业务划分)
        /// 所为的业务对象,就有可以一个数据持久化对象,通过TypeName可以划分为N个业务对象</param>
        /// <returns>导入模板中有非空约束的配置节集合</returns>
        public XmlNodeList GetNotEmptyNodes(string className, string typeName)
        {
            XmlNodeList reVal = null;
            if (string.IsNullOrEmpty(className))
                throw new ArgumentNullException("className");
            var strTypeNamePath = "";
            if (!String.IsNullOrEmpty(typeName))
                strTypeNamePath = "/" + typeName;
            var xPath = "Setting/" + className + strTypeNamePath + "/" + ImportKeyInfo.CHECKS + "/" + ImportKeyInfo.EXISTS + "/" + ImportKeyInfo.ITEM + "[@MinLength>0]";
            reVal = m_XmlReader.GetNodeList(xPath);
            return reVal;
        }

        /// <summary>
        /// 通过指定的对象信息及列名,获取列的配置节
        /// </summary>
        /// <param name="className">对象类型名称</param>
        /// <param name="typeName">对象类别名称(对象的二级业务划分)
        /// 所为的业务对象,就有可以一个数据持久化对象,通过TypeName可以划分为N个业务对象</param>
        /// <param name="columnName">导入模板中的列名</param>
        /// <returns>列的配置节</returns>
        public XmlNode GetColumnItem(string className, string typeName, string columnName)
        {
            XmlNodeList reVal = null;
            if (string.IsNullOrEmpty(className))
                throw new ArgumentNullException("className");
            var strTypeNamePath = "";
            if (!String.IsNullOrEmpty(typeName))
                strTypeNamePath = "/" + typeName;
            var xPath = "Setting/" + className + strTypeNamePath + "/" + ImportKeyInfo.COLUMNS  + "/" + ImportKeyInfo.ITEM + "[@Name='" + columnName + "']";
            reVal = m_XmlReader.GetNodeList(xPath);
            if (reVal == null || reVal.Count == 0)
                throw new ArgumentException("找不到ColumnItem[" + columnName + "]");
            if (reVal.Count > 1)
                throw new ArgumentException("找到多个ColumnItem[" + columnName+ "]");
            return reVal[0];
        }

    }
}
